﻿namespace Site2AppWP8
{
    using System;
    using System.Windows;
    using System.Windows.Navigation;
    using Microsoft.Phone.Controls;
    using Site2AppWP8.Config;

    public partial class WebDialogOverlay : Overlay
    {
        private static Uri blankPage = new Uri("about:blank", UriKind.RelativeOrAbsolute);

        private MainPage parentPage;
        private Rule redirectRule;

        public WebDialogOverlay(MainPage parentPage)
            : base(parentPage)
        {
            this.InitializeComponent();

            this.parentPage = parentPage;
            this.RefreshLayout(Application.Current.Host.Content.ActualHeight, Application.Current.Host.Content.ActualWidth);
        }

        public void StartWebDialog(Uri dialogUri, Rule redirectRule)
        {
            this.redirectRule = redirectRule;

            this.Browser.Navigate(dialogUri);

            this.LayoutRoot.Height = this.parentPage.LayoutRoot.ActualHeight;
            this.LayoutRoot.Width = this.parentPage.LayoutRoot.ActualWidth;
        }

        protected override void RefreshLayout(double height, double width)
        {
            this.LayoutRoot.Height = height;
            this.LayoutRoot.Width = width;
        }

        private void Browser_NavigationFailed(object sender, NavigationFailedEventArgs e)
        {
            // Remove the progress bar if we need to show an error message in the browser
            this.parentPage.HideOverlay();

            MessageBox.Show("A navigation error has occured. This could be due to network connectivity or server issue. Please check your network settings and try again.");
        }

        private void Browser_Navigating(object sender, NavigatingEventArgs e)
        {
            this.parentPage.ShowProgresBarOverlay();
        }

        private void Browser_LoadCompleted(object sender, NavigationEventArgs e)
        {
            this.InjectLoadWindowCloseSpy();

            if (System.Text.RegularExpressions.Regex.IsMatch(e.Uri.AbsoluteUri, this.redirectRule.RedirectOnMatchRegex))
            {
                this.Browser.TryToRunScript("(function() { window.external.notify('BROWSERMATCH~~' + document.documentElement.innerHTML); })();");
            }
            else
            {
                this.parentPage.ShowOverlay(this);
            }
        }

        private void Browser_ScriptNotify(object sender, NotifyEventArgs e)
        {
            var content = e.Value.Split(new string[] { "~~" }, StringSplitOptions.None);

            if (content[0].Equals("BROWSERMATCH", StringComparison.InvariantCultureIgnoreCase))
            {
                string iframeToInject =
                    "(function() {\n" +
                        "if (!document.getElementById('wpDialogFrame')) {\n" +
                            "var iframeToInject = document.createElement('iframe');\n" +
                            "iframeToInject.setAttribute('style', 'display:none');\n" +
                            "iframeToInject.setAttribute('id', 'wpDialogFrame');\n" +
                            "document.body.appendChild(iframeToInject);\n" +
                        "}\n" +
                        "document.getElementById('wpDialogFrame').contentWindow.document.write('" + content[1].Replace("\n", string.Empty) + "');\n" +
                        "window.external.notify('BROWSERHIDEOVERLAY~~WebDialogOverlay');\n" +
                    "})();";

                this.parentPage.Browser.TryToRunScript(iframeToInject);

                return;
            }

            if (content[0].Equals("WINDOWCLOSE", StringComparison.InvariantCultureIgnoreCase))
            {
                string hideOverlayScriptToInject = "(function() {\n" +
                                                      "window.external.notify('BROWSERHIDEOVERLAY~~WebDialogOverlay');" +
                                                    "})();";

                this.parentPage.Browser.TryToRunScript(hideOverlayScriptToInject);

                return;
            }
        }

        private void InjectLoadWindowCloseSpy()
        {
            if (!this.Browser.Source.Equals(blankPage))
            {
                var scriptString = "(function() {\n" +
                                    "var closeWindow = window.close;\n" +
                                    "window.close = function() {\n" +
                                        "console.log('intercepted window.close');\n" +
                                        "window.external.notify('WINDOWCLOSE~~' + window.location.href);\n" +
                                        "return;\n" +
                                    "};\n" + // end of window.close override
                                "})();";

                this.Browser.TryToRunScript(scriptString);
            }
        }
    }
}
